from django.conf import settings
from django.db.models import Q, Count
from django.http import JsonResponse, HttpResponse, FileResponse
from django.views.decorators.http import require_http_methods
from django.core.paginator import Paginator
import json
from django.core import serializers
from wulabapp.models import Article, Software, EducationUrl, News
from django.core.mail import send_mail


@require_http_methods(["POST"])
def add_article(request):
    if request.method == 'POST':
        response = {}
        try:
            body = json.loads(request.body)
            title = body['title']
            if Article.objects.filter(title=title).exists():
                raise ValueError("已经存在具有相同标题的文章。")
            author = body['author']
            journal = body['journal']
            tags = body['tags']
            img_src = body['img_src']
            pdf_src = body['pdf_src']
            pub_year = body['pub_year']
            page_info = body['page_info']
            index = body['index']
            obj = Article(title=title, author=author, journal=journal, tags=tags, img_src=img_src, pdf_src=pdf_src,
                          pub_year=pub_year, page_info=page_info, index=index)
            obj.save()
            response = {
                "success": True,
            }
        except ValueError as ve:
            # 如果发现具有相同标题的记录，返回错误信息
            response = {
                "msg": ve.args[0],
                "success": False,
            }
        except Exception as e:
            response = {
                "msg": str(e),
                "success": False,
            }

        return JsonResponse(response)


@require_http_methods(["POST"])
def get_articles(request):
    response = {}
    if request.method == 'POST':
        try:
            is_main_author = json.loads(request.body)['is_main_author']
            all_data = Article.objects.all() if not is_main_author \
                else Article.objects.filter(is_main_author=True)
            all_data = all_data.order_by('-pub_year', '-pub_month').distinct()  # 使用distinct避免相同年份的重复

            def get_index(element):
                return element['fields']['index']

            # 创建一个字典来存储分组后的数据
            grouped_articles = {}
            for article in all_data:
                pub_year = article.pub_year
                index = article.index
                if pub_year not in grouped_articles:
                    grouped_articles[pub_year] = []

                # 将文章添加到对应年份的列表中
                article_json = serializers.serialize("json", [article])
                grouped_articles[pub_year].append(json.loads(article_json)[0])
                grouped_articles[pub_year].sort(key=get_index, reverse=True)

            grouped_articles = sorted(grouped_articles.items(), key=lambda item: item[0], reverse=True)
            grouped_articles = dict(grouped_articles)
            response = {
                "list": grouped_articles,
                "origin_data": json.loads(serializers.serialize("json", all_data)),
                "success": True,
            }
        except Exception as e:
            response = {
                "msg": str(e),
                "success": False,
            }

        return JsonResponse(response)


@require_http_methods(["POST"])
def update_article(request):
    try:
        data = json.loads(request.body)
    except Exception as e:
        return JsonResponse({"error": e}, status=400)

    try:
        article = Article.objects.get(uuid=data['uuid'])
        for key, value in data.items():
            if hasattr(article, key) and key != 'uuid':
                setattr(article, key, value)
    except Exception as e:
        return JsonResponse({"error": e}, status=404)
    article.save()
    return JsonResponse({"message": "Article updated successfully"}, status=200)


@require_http_methods(["POST"])
def add_software(request):
    if request.method == 'POST':
        response = {}
        try:
            body = json.loads(request.body)
            name = body['name']
            if Software.objects.filter(name=name).exists():
                raise ValueError("已经存在具有相同标题的文章。")
            name = body['name']
            src = body['src']
            url = body['url']
            description = body['description']
            obj = Software(name=name, src=src, url=url, description=description)
            obj.save()
            response = {
                "success": True,
            }
        except ValueError as ve:
            # 如果发现具有相同标题的记录，返回错误信息
            response = {
                "msg": ve.args[0],
                "success": False,
            }
        except Exception as e:
            response = {
                "msg": str(e),
                "success": False,
            }

        return JsonResponse(response)


@require_http_methods(["POST"])
def get_softwares(request):
    response = {}
    if request.method == 'POST':
        try:
            all_data = Software.objects.all()
            custom_order = {'AmpliconSeek': 0, "Bendnet": 1, "CellScanner": 2, "Secuer": 3, "HiCapp": 4}

            def custom_priority_sort(item):
                return custom_order.get(item.name, 9999)

            all_data = sorted(list(all_data), key=custom_priority_sort)
            response = {
                "list": json.loads(serializers.serialize("json", all_data)),
                "success": True,
            }
        except Exception as e:
            response = {
                "msg": str(e),
                "success": False,
            }

        return JsonResponse(response)


@require_http_methods(["POST"])
def update_software(request):
    try:
        data = json.loads(request.body)
    except Exception as e:
        print(e)
        return JsonResponse({"error": e}, status=400)

    try:
        software = Software.objects.get(name=data['name'])
        for key, value in data.items():
            if hasattr(software, key):
                setattr(software, key, value)
    except Exception as e:
        return JsonResponse({"error": e}, status=404)
    software.save()
    return JsonResponse({"message": "Software updated successfully"}, status=200)


@require_http_methods(["POST"])
def send_email(request):
    response = {}
    if request.method == 'POST':
        try:
            data = json.loads(request.body)
            subject = data['subject'] or "default subject"
            name = data['firstName'] + ' ' + data['lastName']
            email = data['email']
            message = data['message']
            message_body = f'Name: {name}\nEmail: {email}\nMessage: {message}'
            send_mail(
                subject,
                message_body,
                'multiomics-bjmu@outlook.com',  # 发件人邮箱，
                ['multiomics-bjmu@outlook.com'],  # 收件人邮箱
                fail_silently=False,
            )
            response = {
                "data": data,
                "success": True,
            }
        except Exception as e:
            response = {
                "msg": str(e),
                "success": False,
            }
        return JsonResponse(response)


@require_http_methods(["POST"])
def add_education_url(request):
    if request.method == 'POST':
        response = {}
        try:
            body = json.loads(request.body)
            title = body['title']
            if EducationUrl.objects.filter(title=title).exists():
                raise ValueError("已经存在具有相同标题的教育链接。")
            url = body['url']
            category = body['category']
            img_url = body['img_url'] or ''
            obj = EducationUrl(title=title, url=url, category=category, img_url=img_url)
            obj.save()
            response = {
                "success": True,
                "url": url,
                "category": category,
                "title": title,
            }
        except ValueError as ve:
            # 如果发现具有相同标题的记录，返回错误信息
            response = {
                "msg": ve.args[0],
                "success": False,
            }
        except Exception as e:
            response = {
                "msg": str(e),
                "success": False,
            }

        return JsonResponse(response)


@require_http_methods(["POST"])
def get_education_urls(request):
    response = {}
    if request.method == 'POST':
        try:
            all_data = EducationUrl.objects.all()
            categories = EducationUrl.objects.values_list('category', flat=True).distinct()
            grouped_urls = {}
            for data in all_data:
                category = data.category
                if category not in grouped_urls:
                    grouped_urls[category] = []

                # 将文章添加到对应年份的列表中
                data_json = serializers.serialize("json", [data])
                grouped_urls[category].append(json.loads(data_json)[0])
            grouped_articles = sorted(grouped_urls.items(), key=lambda item: item[0], reverse=True)
            grouped_articles = dict(grouped_articles)
            response = {
                "list": grouped_urls,
                "categories": list(categories),
                "success": True,
            }
        except Exception as e:
            response = {
                "msg": str(e),
                "success": False,
            }

        return JsonResponse(response)


@require_http_methods(["POST"])
def add_news(request):
    if request.method == 'POST':
        try:
            body = json.loads(request.body)
            title = body['title']
            content = body['content']
            year = body['year']
            month = body['month']
            url = body['url']
            if News.objects.filter(content=content).exists():
                raise ValueError("News exists")
            obj = News(title=title, content=content, year=year, month=month, url=url)
            obj.save()
            response = {
                "success": True,
            }
        except ValueError as ve:
            # 如果发现具有相同标题的记录，返回错误信息
            response = {
                "msg": ve.args[0],
                "success": False,
            }
        except Exception as e:
            response = {
                "msg": str(e),
                "success": False,
            }

        return JsonResponse(response)


@require_http_methods(["POST"])
def get_news(request):
    if request.method == 'POST':
        try:
            all_data = News.objects.all().order_by('year').distinct()  # 使用distinct避免相同年份的重复
            # 创建一个字典来存储分组后的数据
            grouped_news = {}
            for news in all_data:
                year = news.year
                month = news.month
                if year not in grouped_news:
                    grouped_news[year] = {}
                if month not in grouped_news[year]:
                    grouped_news[year][month] = []
                # 将文章添加到对应年份的列表中
                news_json = serializers.serialize("json", [news])
                grouped_news[year][month].append(json.loads(news_json)[0])

            grouped_news = sorted(grouped_news.items(), key=lambda item: item[0], reverse=True)
            grouped_news = dict(grouped_news)
            response = {
                "list": grouped_news,
                "origin_data": json.loads(serializers.serialize("json", all_data)),
                "success": True,
            }
        except Exception as e:
            response = {
                "msg": str(e),
                "success": False,
            }

        return JsonResponse(response)


@require_http_methods(["POST"])
def update_news(request):
    if request.method == 'POST':
        try:
            data = json.loads(request.body)
        except Exception as e:
            print(e)
            return JsonResponse({"error": e}, status=400)

        try:
            news = News.objects.get(content=data['content'])
            for key, value in data.items():
                if hasattr(news, key):
                    setattr(news, key, value)
        except Exception as e:
            return JsonResponse({"error": e}, status=404)
        news.save()
        return JsonResponse({"message": "News updated successfully"}, status=200)
